import json
import random
from gensim.models.word2vec import Word2Vec
import os
import analyse
import numpy as np

base_path = os.path.dirname(analyse.__file__)


def load_word_data():
    data_path = ['job', 'city', 'company', 'education']
    words = list()
    words.append([''])
    for path in data_path:
        with open(os.path.join(base_path, 'data', f'{path}_name.json'), mode='r', encoding='utf8') as f:
            d = json.load(f)
            if path == 'company':
                words.extend([[i[path]] for i in d])
            else:
                words.extend([[i[f'{path}_name']] for i in d])
    return words


def train_model(corpus, vector_size=10):
    """

    :param vector_size: 向量维度
    :param corpus: 语料库
    :return:
    """
    return Word2Vec(corpus, window=5, min_count=1, vector_size=vector_size)


def get_vec(model, job: dict):
    vec = [
        job.get("salary_upper_limit", 0),
        job.get("salary_lower_limit", 0),
        job.get("experience_upper_limit", 0),
        job.get("experience_lower_limit", 0),
        job.get("company_size_upper_limit", 0),
        job.get("company_size_lower_limit", 0),
    ]
    vec.extend(model.wv[job.get('company', '')])
    vec.extend(model.wv[job.get('city_name', '')])
    vec.extend(model.wv[job.get('education_name', '')])
    return vec


def job_predict(user_job: dict):
    words = load_word_data()
    model = train_model(words)
    user_vec = get_vec(model, user_job)
    with open(os.path.join(base_path, 'data', 'predict_data.json'), mode='r', encoding='utf8') as f:
        data = json.load(f)
        similarity_d = dict()
        for job in data:
            job_name = job['job_name']
            job_vec = get_vec(model, job)
            r = np.dot(user_vec, job_vec) / (np.linalg.norm(user_vec) * np.linalg.norm(job_vec))
            similarity_d[job_name] = r

    max_similarity = max(similarity_d.values())
    min_similarity = min(similarity_d.values())
    mean_similarity = (max_similarity + min_similarity) / 2
    candidate_job = list()
    for job, sim in similarity_d.items():
        if sim > mean_similarity:
            candidate_job.append(job)
    return random.choice(candidate_job)
